home *** CD-ROM | disk | FTP | other *** search
-
- A Pixel-Precision Method For Detecting Sprite Collision
- v 1.0
- by Mark Mackey
-
- ---
- Introduction
- ----
-
- A common query on the USENET newsgroup rec.games.programmer over the
- years has been how to do fast pixel-precision collision detection. A
- number of people have presented some excellent algorithms for extending
- and speeding up bounding-box collision detection between large numbers of
- objects (for instance, dividing the play area into subfields and sorting
- the sprites into these subfields, thus greatly reducing the number of
- sprite-sprite collisions that have to be checked in the first place).
-
- However, there have been little information available on how to detect
- collisions efficiently at the pixel level. I thus present here some code
- from my game XQuest (blatant plug) which checks for collisions at the
- pixel level. The routine assumes that the bounding boxes for the two
- sprites overlap, and hence should be relatively easy to add to an
- existing bounding-box collision detection routine. This code is fast,
- relatively efficient in terms of space (requiring 4 bytes per row of each
- sprite), and even works! The one limitation is that sprites are assumed
- to be 32 pixels or less in width. For larger sprites, you could either
- treat them as 2 or more 32-pixel wide objects, or with a bit of creative
- thought this routine could be rewritten to allow for 64-pixel wide
- objects on the 386 (left as an exercise for the reader :).
-
- The code in the enclosed file COLLIDE.PAS is organised as a Turbo Pascal
- unit, but all of the essential code is in assembly language and could be
- easily ported to work under C or in a pure asm program. If any of the
- Pascalisations confuse you just let me know and I'll explain :). Also, if
- you need a version of this code to work on a 286 then let me know and
- I'll send it to you (but be warned: it's not nearly as nice :).
-
- ---
- The Algorithm
- ---
-
- The first step is to create a 'transparency' mask for each sprite. The
- mask consists of a dword for each row of the sprite, with each bit being
- a 0 if the corresponding pixel is 'empty', and a 1 otherwise. For
- example, if a row of your sprite looked like (colour indexes, 0 being
- transparent)
-
- 0 0 0 1 23 42 0 1 56 0 0 0 0 0
-
- the the corresponging mask bytes would be
-
- 00011101 10000000 00000000 00000000 = 1D 80 00 00
-
- The MakeMask procedure given will produce such a mask from a sprite
- supplied in the XLib linear bitmap format (with pixels of colour zero
- being transparent), and is easily adaptable to your own sprite format.
-
- OK, now the hard part. We have found in our general-purpose bounding-box
- collision detection routine that two sprites' bounding boxes have
- collided (ie their masks overlap).
-
- Let the leftmost sprite have (x1,y1) as the coords of its top left
- corner, and the rightmost one (x2,y2). Take the mask entry for row
- |y2-y1| of the topmost sprite and shift it left by the difference in the
- x-coordinates (x2-x1). AND this value with the 1st mask entry of the
- lower sprite. If the result is non-zero then a collision occurred on this
- row. If not, then shift row |y2-y1+1| and compare it to row 2 of the
- lower sprite, and so on, until you reach the bottom of one of the
- sprites. If no collision has been detected by this time, then the sprites
- didn't collide. Simple, eh?
-
- This routine is quite fast, requiring only a MOV, a SHL and an AND for
- each row checked, and only checking those rows that overlap.
-
- ---
- The Legal Bit
- ---
-
- This software is (C) Copyright 1995 Mark Mackey. Permission is given to
- distribute this code freely, or to distribute modified forms of this
- software provided that the author is acknowledged and this copyright
- notice retained. Permission is also given to utilise this code in
- original or modified form in any software provided that the author is
- acknowledged.
-
- I can be contacted by
-
- Email: mdm1004@cus.cam.ac.uk
- WWW: http://www.ch.cam.ac.uk/MMRG/mdm.html
- Snail: c/o Trinity Hall,
- Cambridge CB2 1TJ
- UK
-
- These addresses will be in use until at least October 1996. Please let me
- know if you found this code helpful/useful/rubbish/whatever or if you
- improve it :)
-
-